<script setup lang="ts">
import { useRequest } from 'ahooks-vue'
import { DatePicker, FormGrid, FormItem, FormLayout, Input, InputNumber, Radio, Select } from '@formily/element-plus'
import type { Field } from '@formily/core'
import { createForm, isField, onFieldInit, onFormInit } from '@formily/core'
import { ElMessage } from 'element-plus'
import { ref } from 'vue'
import { useRoute } from 'vue-router'
import { merge } from 'lodash-es'
import SchemaForm from '@/components/SchemaForm'
import { getSchoolDictInfo, getStudent, getStudentScore, updateStudent } from '@/api/student'
import type { Dept, Student } from '@/types/user'
import type { Province } from '@/hooks/useAddress'
import useAddress from '@/hooks/useAddress'
import { StudentScore, baseInfoSchema, schoolInfoSchema, scoreInfoSchema } from '@/views/student/schema'
import { useDict } from '@/utils/dict'

const { sys_user_sex } = useDict('sys_user_sex')
const route = useRoute()
const { run: doQuery, loading: infoLoading } = useRequest(
  getStudent,
  {
    manual: true,
  },
)
const { run: doUpdate, loading } = useRequest(updateStudent, { manual: true, throttleInterval: 500 })

async function handleQuery() {
  const query = Promise.all([doQuery(route.params.idCard as string) as ReturnType<typeof getStudent>, getStudentScore(route.params.idCard as string)])
  const [{ data: student = {} }, { data: source = {} }] = await query
  return {
    data: merge(
      student,
      Object.keys(StudentScore()).reduce((pre, key) => ({ ...pre, [key]: (source as Record<string, any>)[key] }), {}),
    ),
  }
}

const transformerDept = (data: Dept[]) => data.map(item => ({ label: item.deptName, value: item.deptName, id: item.deptId }))

async function querySchoolDictByPre(field: Field, dataSource?: { label: string; value: string; id: number }[], value?: string) {
  const pre = dataSource?.find(item => item.value === value)
  if (pre) {
    field.loading = true
    const { data } = await getSchoolDictInfo(pre.id)
    field.dataSource = transformerDept(data)
    if (field.dataSource.findIndex(item => item.value === field.value) === -1)
      field.value = null
    field.loading = false
  }
}
const form = createForm<Partial<Student> & { studentIdCard: string }>({
  initialValues: {},
  editable: false,
  effects: () => {
    onFormInit(async (form1) => {
      const { data } = await handleQuery()
      form1.setValues(data, 'overwrite')
    })
    onFieldInit('layout.province', async (field) => {
      if (isField(field)) {
        field.loading = true
        const data = await useAddress((data: Record<string, Province>) => Object.values(data).map(value => ({ label: value.name, value: value.name })))
        field.loading = false
        field.dataSource = data
      }
    })
    onFieldInit('layout.sex', (field) => {
      if (isField(field))
        field.dataSource = sys_user_sex.value
    })
    onFieldInit('layout.studentCollege', async (field) => {
      if (isField(field)) {
        field.loading = true
        const { data } = await getSchoolDictInfo(-1)
        field.dataSource = transformerDept(data)
        field.loading = false
      }
    })
  },
})

async function handleSubmit() {
  await form.submit(values => doUpdate(values))
  ElMessage({ message: '修改成功', type: 'success' })
  const { data } = await handleQuery()
  form.setValues(data, 'shallowMerge')
}

const editable = ref(false)

async function toggleEditable() {
  if (editable.value) {
    const { data } = await handleQuery()
    form.setValues(data, 'overwrite')
  }
  editable.value = !editable.value
  form.setFormState((state) => {
    state.editable = editable.value
  })
}
</script>

<template>
  <div class="w-full">
    <ElRow v-loading="infoLoading" class="pl-4 pt-4">
      <ElButton v-loading="loading" type="primary" @click="handleSubmit">
        保存
      </ElButton>
      <ElButton @click="toggleEditable">
        {{ editable ? '取消' : '修改' }}
      </ElButton>
    </ElRow>
    <ElRow v-loading="infoLoading" :gutter="20" class="p-4">
      <ElCol :span="14" :xs="24">
        <ElCard class="box-card">
          <template #header>
            <div class="clearfix">
              <span>学生基础信息</span>
            </div>
          </template>
          <div class="w-full">
            <SchemaForm
              :schema="baseInfoSchema"
              :components="{ FormItem, Input, DatePicker, Select, Radio, FormGrid }"
              :form="form"
            />
          </div>
        </ElCard>
      </ElCol>
      <ElCol :span="5" :xs="24">
        <ElCard class="box-card">
          <template #header>
            <div class="clearfix">
              <span>学校信息</span>
            </div>
          </template>
          <div class="w-full">
            <SchemaForm
              :schema="schoolInfoSchema"
              :components="{ FormItem, FormLayout, Input, Select }"
              :form="form"
              :scope="{ querySchoolDictByPre }"
            />
          </div>
        </ElCard>
      </ElCol>
      <ElCol :span="5" :xs="24">
        <ElCard class="box-card">
          <template #header>
            <div class="clearfix">
              <span>录取信息</span>
            </div>
          </template>
          <div class="w-full">
            <SchemaForm
              :schema="scoreInfoSchema"
              :components="{ FormItem, FormLayout, Input, InputNumber }"
              :form="form"
            />
          </div>
        </ElCard>
      </ElCol>
    </ElRow>
  </div>
</template>
